// 做鉴权的， 获取用户权限的，例如 不同用户对应菜单

// 登录过的，能访问其他页面，不能访问登录页
// 没登录过的，能访问登录页，不能访问其他页面

// 拿到路由
import router from "@/router/index"
// 引入 nprogress js
import NProgress from "nprogress"
// 引入 nprogress css
import "nprogress/nprogress.css"
import { getToken } from "@/utils/auth"
// 菜单权限 1. 导入 useUserStore
import { useUserStore } from "./stores/user"
// 菜单权限 2. 导入 usePermissionStore
import { usePermissionStore } from "./stores/permission"

// 不要 NProgress 某个加载 特效
NProgress.configure({ showSpinner: false })

// 白名单逻辑 1. 配置哪些页面不需要做Token校验，就可以访问 的白名单
const whiteList = ["/login"]
// 每个页面加载之前，判断页面是否登录过
// 新版本，是可以写 async await  返回 通过 true 和 不通过 false
router.beforeEach(async (to) => {
  // 开启 loading
  NProgress.start()
  // 白名单逻辑 2. 从 pinia 或者 localStorage 获取 token
  const hasToken = getToken()
  // 菜单权限 3. 使用 useUserStore
  const userStore = useUserStore()
  // 菜单权限 4. 使用 usePermissionStore
  const permissionStore = usePermissionStore()
  // 白名单逻辑 3. 如果有token
  if (hasToken) {
    if (to.path === "/login") {
      // 白名单逻辑 3-1. 已经登录了，去登录页，重定向到首页
      NProgress.done()
      return {
        path: "/",
        replace: true
      }
    } else {
      // 菜单权限 5. 用token 换取 用户信息， 因为 token也有可能是伪造的，但不能一刷新，就用token 换取 用户信息，要先判断store，有无用户信息
      try {
        const hasRoles = userStore.state.roles.length > 0
        // 菜单权限 6. 判断store，有无 **用户角色** 信息，有就路由放行，不执行下方逻辑
        if (hasRoles) {
          NProgress.done()
          return true
        }
        // 菜单权限 7. 如果 stroe 无角色，请求 **userStore.getUserInfo()** 接口，获取用户角色和其他信息
        // 菜单权限 7-1. 这里的token 有可能是伪造的，加 trycatch
        await userStore.getUserInfo()
        // const roles = userStore.state.roles
        // 菜单权限 8. 用角色 对应的远程路由 来筛选要注册的本地异步路由
        const routes = await permissionStore.generateRoutes()
        // 菜单权限 9. 要注册的本地异步路由 添加到映射表中
        routes.forEach(router.addRoute)
        // 菜单权限 10. 添加完路由之后，路由可能异步的，你访问的时候刚加上去异步路由，没有效果，再router.push跳一次，让他生效
        return router.push(to.path)
      } catch (e) {
        // 菜单权限 7-2. 请求 getUserInfo 接口，失败说明 token 是伪造的, 或者过期，退出登录，
        console.log(e)
        // 菜单权限 7-2-1. 退出登录
        userStore.logout()
        NProgress.done()
        // 菜单权限 7-2-2. 重定向 数据
        return "/login?redirect=" + to.path
      }
    }
  } else {
    // 白名单逻辑 4. 如果没有 token, 但在白名单可访问页面，可以访问
    if (whiteList.includes(to.path)) {
      NProgress.done()
      return true
    }
    // 白名单逻辑 5. 如果没有 token, 也不在白名单可访问页面，不可以访问其他页面
    // 跳转到登录页
    return {
      path: "/login",
      // 白名单逻辑 5-1. 由于上面原因，导致 刷新 和 跳转 其他页面, 跳转 /login ，要携带 重定向路径 和 其他参数
      query: {
        redirect: to.path, // 重定向路径
        ...to.query // 有其他参数
      }
    }
  }
})
